package com.sk.photo_album;

import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.GridLayoutManager;

import com.bumptech.glide.Glide;
import com.sk.photo_album.adapter.AlbumAdapter;
import com.sk.photo_album.adapter.SpinnerAdapter;
import com.sk.photo_album.databinding.ActivityAlbumBinding;
import com.sk.photo_album.util.SpacesItemDecoration;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 媒体选择
 */
public class AlbumActivity extends AppCompatActivity {

    ExecutorService executor;

    ActivityAlbumBinding binding;

    AlbumAdapter albumAdapter;

    SpinnerAdapter spinnerAdapter;

    /**
     * 相机拍照后存储图片位置
     */
    private String currentPhotoPath;

    /**
     * 相机回调
     */
    ActivityResultLauncher<Intent> cameraResultLauncher;

    /**
     * 裁切回调
     */
    ActivityResultLauncher<Intent> cropResultLauncher;

    /**
     * 设置参数
     */
    AlbumBuilder builder;

    /**
     * 媒体数据
     */
    private Map<String, List<MediaInfo>> mediaMap;

    /**
     * 需要查询的数据库字段
     */
    private final String[] projImage = {MediaStore.Images.Media._ID
            , MediaStore.Images.Media.DATA
            , MediaStore.Images.Media.SIZE
            , MediaStore.Images.Media.DISPLAY_NAME};

    private final String[] projVideo = {MediaStore.Video.Media._ID
            , MediaStore.Video.Media.DATA
            , MediaStore.Video.Media.SIZE
            , MediaStore.Video.Media.DURATION
            , MediaStore.Video.Media.DISPLAY_NAME};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityAlbumBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // 获取设置参数
        builder = AlbumBuilder.getInstance();

        // 相册选择
        spinnerAdapter = new SpinnerAdapter();
        binding.spinner.setAdapter(spinnerAdapter);

        // 媒体文件显示
        albumAdapter = new AlbumAdapter(builder.getShowCamera(), builder.getMaxSelect());
        // 设置列表
        binding.albumList.setLayoutManager(new GridLayoutManager(this, 4));
        binding.albumList.addItemDecoration(new SpacesItemDecoration(4, 4, 4, 4));
        binding.albumList.setAdapter(albumAdapter);

        // 初始化监听
        initListener();

        // 获取相册数据
        getMedia();
    }

    private void initListener() {
        // 关闭
        binding.toolbarBack.setOnClickListener(v -> finish());
        // 完成
        binding.complete.setOnClickListener(v -> {
            if (albumAdapter.getMediaCheckList().size() == 0) {
                Toast.makeText(this, "请选择文件", Toast.LENGTH_SHORT).show();
            } else {
                callBack(albumAdapter.getMediaCheckList());
            }
        });
        // 选择选择监听
        binding.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                albumAdapter.reloadData(mediaMap.get(spinnerAdapter.getItem(position)));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        // 媒体点击监听
        albumAdapter.setOnItemClickListener((view, position) -> {
            MediaInfo mediaInfo = albumAdapter.getMediaItem(position);
            if (mediaInfo.getType() == null) {
                // 拍照
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                try {
                    File photoFile = createImageFile();
                    Uri cameraUri = FileProvider.getUriForFile(this, builder.getAuthority(), photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
                    cameraResultLauncher.launch(takePictureIntent);
                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(this, "相机启动失败！", Toast.LENGTH_SHORT).show();
                }
            } else {
                if (mediaInfo.getType() == Media.MEDIA_TYPE_VIDEO) {
                    mediaInfo.setChecked(!mediaInfo.isChecked());
                    albumAdapter.notifyItemChanged(position);
                } else {
                    // 显示预览页面
                    Glide.with(this)
                            .load(mediaInfo.getPath())
                            .into(binding.preview);
                    binding.title.setText(String.format(Locale.CHINA, "%d/%d", position, albumAdapter.getItemCount() - 1));
                    binding.previewLayout.setAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_preview_show));
                    binding.previewLayout.setVisibility(View.VISIBLE);
                }
            }
        });
        // 预览关闭监听
        binding.preview.setOnClickListener(v -> previewHidden());
        binding.close.setOnClickListener(v -> previewHidden());

        // 相机回调
        cameraResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
            if (result.getResultCode() == RESULT_OK) {
                try {
                    // 将图片刷新到图库
                    galleryAddPic(currentPhotoPath);

                    if (builder.getCropImage()) {
//                    cropImage(file);
                    } else {
                        // 将地址回传
                        ArrayList<MediaInfo> list = new ArrayList<>();
                        list.add(new MediaInfo(currentPhotoPath, null, null));
                        callBack(list);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        // 裁切回调
        cropResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {

        });
    }

    /**
     * 加载数据
     */
    private void loadData() {
        List<String> keys = new ArrayList<>();
        if (mediaMap.get("全部图片") != null) {
            keys.add("全部图片");
        }
        if (mediaMap.get("全部视频") != null) {
            keys.add("全部视频");
        }
        for (String key : mediaMap.keySet()) {
            if (!key.equals("全部图片") && !key.equals("全部视频")) {
                keys.add(key);
            }
        }

        spinnerAdapter.reloadData(keys);
    }

    /**
     * 隐藏预览页面
     */
    private void previewHidden() {
        if (binding.previewLayout.getVisibility() == View.VISIBLE) {
            binding.previewLayout.setVisibility(View.GONE);
            binding.previewLayout.setAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_preview_hidden));
        }
    }

    /**
     * 回调
     */
    private void callBack(ArrayList<MediaInfo> list) {

        if (builder.getCallBack() != null) {
            List<String> paths = new ArrayList<>();
            for (MediaInfo mediaInfo : list) {
                paths.add(mediaInfo.getPath());
            }
            builder.getCallBack().onComplete(paths);
        }
        finish();
    }

    /* -------------------相册相关------------------------ */

    private Map<String, List<MediaInfo>> getPhotoAlbumList() {

        if (builder.getMediaType() != Media.MEDIA_TYPE_ALL && builder.getMediaType() != Media.MEDIA_TYPE_IMAGE) {
            return null;
        }

        Cursor cursor = getApplicationContext().getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projImage,
                builder.getImageSelection(),
                builder.getImageSelectionArgs(),
//                MediaStore.Images.Media.DATE_ADDED
                MediaStore.Images.Media.DATE_MODIFIED + " desc"
        );

        if (cursor != null) {

            Map<String, List<MediaInfo>> albumMap = new HashMap<>();
            // 所有图片
            List<MediaInfo> allMedia = new ArrayList<>();
            albumMap.put("全部图片", allMedia);

            while (cursor.moveToNext()) {
                try {
                    // 地址
                    String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
                    // 名称
                    String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));

                    String album = getAlbumName(path);
                    List<MediaInfo> mediaList = albumMap.get(album);
                    if (mediaList == null) {
                        mediaList = new ArrayList<>();
                        albumMap.put(album, mediaList);
                    }

                    MediaInfo mediaInfo = new MediaInfo(path, name, album);
                    mediaList.add(mediaInfo);
                    allMedia.add(mediaInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            cursor.close();

            return albumMap;
        }

        return null;
    }

    private Map<String, List<MediaInfo>> getVideoAlbumList() {

        if (builder.getMediaType() != Media.MEDIA_TYPE_ALL && builder.getMediaType() != Media.MEDIA_TYPE_VIDEO) {
            return null;
        }

        Cursor cursor = getApplicationContext().getContentResolver().query(
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                projVideo,
                builder.getVideoSelection(),
                builder.getVideoSelectionArgs(),
//                MediaStore.Video.Media.DATE_ADDED
                MediaStore.Images.Media.DATE_MODIFIED + " desc"
        );

        if (cursor != null) {
            Map<String, List<MediaInfo>> albumMap = new HashMap<>();
            // 所有视频
            List<MediaInfo> allMedia = new ArrayList<>();
            albumMap.put("全部视频", allMedia);

            while (cursor.moveToNext()) {
                try {
                    // 地址
                    String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
                    // 名称
                    String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
                    //视频时长
                    long duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));

                    String album = getAlbumName(path);
                    List<MediaInfo> mediaList = albumMap.get(album);
                    if (mediaList == null) {
                        mediaList = new ArrayList<>();
                        albumMap.put(album, mediaList);
                    }
                    MediaInfo mediaInfo = new MediaInfo(path, name, album, duration);
                    mediaList.add(mediaInfo);
                    allMedia.add(mediaInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            cursor.close();

            return albumMap;
        }

        return null;
    }

    private String getAlbumName(String path) {
        String[] folders = path.split(File.separator);
        if (folders.length > 1) {
            return folders[folders.length - 2];
        }

        return "默认相册";
    }

    private void getMedia() {
        // 创建单线程线程池
        if (executor == null) {
            executor = Executors.newSingleThreadExecutor();
        }

        executor.execute(() -> {
            // 获取图片列表
            Map<String, List<MediaInfo>> imageMap = getPhotoAlbumList();
            if (imageMap != null) {
                mediaMap = imageMap;
            } else {
                mediaMap = new HashMap<>();
            }
            // 获取视频列表
            Map<String, List<MediaInfo>> videoMap = getVideoAlbumList();
            if (videoMap != null) {
                for (String key : videoMap.keySet()) {
                    if (mediaMap.get(key) == null) {
                        mediaMap.put(key, new ArrayList<>());
                    }
                    if (videoMap.get(key) != null) {
                        Objects.requireNonNull(mediaMap.get(key))
                                .addAll(Objects.requireNonNull(videoMap.get(key)));
                    }
                }
            }

            // 显示内容
            runOnUiThread(this::loadData);
        });
    }

    /* -------------------相机相关------------------------ */

    private void cropImage(File imageFile) {
//        Intent intent = new Intent("com.android.camera.action.CROP");
//
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//            Uri contentUri = FileProvider.getUriForFile(this, "com.leon.crop.fileprovider", file);
//            intent.setDataAndType(contentUri, "image/*");
//        } else {
//            intent.setDataAndType(Uri.fromFile(file), "image/*");
//        }
    }

    /**
     * 保存图片
     */
    private File createImageFile() throws IOException {
        // 生成照片文件名称
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
//        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File storageDir = new File(builder.getSavePath());
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        return image;
    }

    /**
     * 将照片添加到图库
     *
     * @param path 图片地址
     */
    private void galleryAddPic(String path) {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(path);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }

}